package vip.zhenzicheng.nettyadv.server;

import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.ReadTimeoutException;
import io.netty.util.ReferenceCountUtil;
import vip.zhenzicheng.nettyadv.constant.MessageType;
import vip.zhenzicheng.nettyadv.vo.MsgHeader;
import vip.zhenzicheng.nettyadv.vo.MyMessage;

import java.util.logging.Logger;

/**
 * @author zhenzicheng
 * @date 2022-06-14 09:41
 */
public class HeartBeatRespHandler extends ChannelInboundHandlerAdapter {

  private static final Logger LOG = Logger.getLogger(HeartBeatRespHandler.class.getSimpleName());

  @Override
  public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
    MyMessage message = (MyMessage) msg;
    /*是心跳请求*/
    if (message.getMsgHeader() != null && message.getMsgHeader().getType() == MessageType.HEARTBEAT_REQ.value()) {
      MyMessage heartBeatResp = buildHeartBeat(); // 构建心跳应答报文
      LOG.info("心跳应答：" + heartBeatResp);
      ctx.writeAndFlush(heartBeatResp);
      ReferenceCountUtil.release(msg);
    } else {
      ctx.fireChannelRead(msg); /*不是心跳请求就向后传递*/
    }
  }

  private MyMessage buildHeartBeat() {
    MyMessage message = new MyMessage();
    MsgHeader msgHeader = new MsgHeader();
    msgHeader.setType(MessageType.HEARTBEAT_RESP.value());
    message.setMsgHeader(msgHeader);
    return message;
  }

  @Override
  public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
    if (cause instanceof ReadTimeoutException) {
      LOG.warning("客户端长时间未通信，可能已经宕机，关闭链路");
      SecurityCenter.removeLoginUser(ctx.channel().remoteAddress().toString());
      ctx.close();
    }
    super.exceptionCaught(ctx, cause);
  }

  @Override
  public void channelInactive(ChannelHandlerContext ctx) throws Exception {
    LOG.warning("客户端已关闭连接");
    super.channelInactive(ctx);
  }
}
